package cn.cdutetc.library.service.impl;

import cn.cdutetc.library.common.exception.BizException;
import cn.cdutetc.library.entity.dto.BorrowDTO;
import cn.cdutetc.library.entity.dto.BorrowVO;
import cn.cdutetc.library.entity.enums.BookStatusEnum;
import cn.cdutetc.library.entity.enums.BorrowStatusEnum;
import cn.cdutetc.library.entity.pojo.Book;
import cn.cdutetc.library.entity.pojo.BookItem;
import cn.cdutetc.library.entity.pojo.Borrow;
import cn.cdutetc.library.entity.pojo.BorrowRule;
import cn.cdutetc.library.entity.pojo.FeeRecord;
import cn.cdutetc.library.entity.pojo.User;
import cn.cdutetc.library.mapper.BookItemMapper;
import cn.cdutetc.library.mapper.BookMapper;
import cn.cdutetc.library.mapper.BorrowMapper;
import cn.cdutetc.library.mapper.BorrowRuleMapper;
import cn.cdutetc.library.mapper.FeeRecordMapper;
import cn.cdutetc.library.mapper.UserMapper;
import cn.cdutetc.library.service.BorrowService;
import cn.cdutetc.library.service.NotificationService;
import cn.cdutetc.library.service.SystemConfigService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 借阅服务实现类
 */
@Service
public class BorrowServiceImpl extends ServiceImpl<BorrowMapper, Borrow> implements BorrowService {

    @Autowired
    private BookItemMapper bookItemMapper;

    @Autowired
    private BookMapper bookMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private BorrowRuleMapper borrowRuleMapper;

    @Autowired
    private FeeRecordMapper feeRecordMapper;

    @Autowired
    private SystemConfigService systemConfigService;
    
    @Autowired
    private NotificationService notificationService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer borrowBook(BorrowDTO borrowDTO) {
        // 检查用户是否存在
        User user = userMapper.selectById(borrowDTO.getUserId());
        if (user == null) {
            throw new BizException("用户不存在");
        }

        // 检查图书条目是否存在
        BookItem bookItem = bookItemMapper.selectById(borrowDTO.getItemId());
        if (bookItem == null) {
            throw new BizException("图书条目不存在");
        }

        // 检查图书状态是否为在库
        if (!BookStatusEnum.IN_STOCK.getCode().equals(bookItem.getStatus())) {
            throw new BizException("图书不在库，无法借阅");
        }

        // 获取图书信息
        Book book = bookMapper.selectById(bookItem.getBookId());
        if (book == null) {
            throw new BizException("图书不存在");
        }

        // 检查图书可用数量
        if (book.getAvailableCopies() <= 0) {
            throw new BizException("图书无可用副本");
        }

        // 获取用户借阅规则
        BorrowRule borrowRule = getBorrowRuleByUserRole(user.getRole());
        if (borrowRule == null) {
            throw new BizException("未找到用户借阅规则");
        }

        // 检查用户是否已借阅该图书
        LambdaQueryWrapper<Borrow> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Borrow::getUserId, borrowDTO.getUserId())
                .eq(Borrow::getItemId, borrowDTO.getItemId())
                .eq(Borrow::getStatus, "borrowing");
        if (this.count(queryWrapper) > 0) {
            throw new BizException("您已借阅该图书，无法重复借阅");
        }

        // 检查用户借阅数量是否已达上限
        LambdaQueryWrapper<Borrow> countWrapper = new LambdaQueryWrapper<>();
        countWrapper.eq(Borrow::getUserId, borrowDTO.getUserId())
                .eq(Borrow::getStatus, "borrowing");
        if (this.count(countWrapper) >= borrowRule.getMaxBorrowCount()) {
            throw new BizException("您已达到最大借阅数量限制：" + borrowRule.getMaxBorrowCount() + "本");
        }

        try {
            // 创建借阅记录
            Borrow borrow = new Borrow();
            borrow.setUserId(borrowDTO.getUserId());
            borrow.setItemId(borrowDTO.getItemId());
            borrow.setBorrowDate(LocalDateTime.now());
            borrow.setDueDate(borrow.getBorrowDate().plusDays(borrowRule.getMaxBorrowDays()));
            borrow.setStatus("borrowing");
            borrow.setRenewCount(0);
            this.save(borrow);

            // 更新图书条目状态为借出
            bookItem.setStatus(BookStatusEnum.BORROWED.getCode());
            bookItemMapper.updateById(bookItem);

            // 更新图书可用数量
            book.setAvailableCopies(book.getAvailableCopies() - 1);
            bookMapper.updateById(book);

            // 发送借阅通知
            try {
                Integer notificationId = notificationService.createBorrowNotification(
                    borrow.getUserId(),
                    borrow.getBorrowId(),
                    2, // 借阅提醒
                    "借阅成功",
                    "您已成功借阅《" + book.getBookName() + "》，请在" + borrow.getDueDate().toLocalDate() + "前归还。"
                );
                if (notificationId == null) {
                    System.err.println("发送借阅通知失败，notificationId为null");
                }
            } catch (Exception e) {
                // 即使通知发送失败，也不应该影响借阅操作本身
                System.err.println("发送借阅通知失败: " + e.getMessage());
                e.printStackTrace();
                // 不再显示错误给用户，只记录日志
            }

            return borrow.getBorrowId();
        } catch (Exception e) {
            // 记录异常信息并重新抛出，确保事务正确回滚
            System.err.println("借阅图书失败: " + e.getMessage());
            throw e;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean returnBook(Integer borrowId) {
        // 检查借阅记录是否存在
        Borrow borrow = this.getById(borrowId);
        if (borrow == null) {
            throw new BizException("借阅记录不存在");
        }

        // 检查借阅状态
        if (BorrowStatusEnum.RETURNED.getCode().equals(borrow.getStatus())) {
            throw new BizException("图书已归还");
        }
        
        // 丢失状态的图书不能直接归还
        if (BorrowStatusEnum.LOST.getCode().equals(borrow.getStatus())) {
            throw new BizException("图书已丢失，无法归还，请先支付赔偿费用");
        }

        // 检查图书条目是否存在
        BookItem bookItem = bookItemMapper.selectById(borrow.getItemId());
        if (bookItem == null) {
            throw new BizException("图书条目不存在");
        }

        // 获取图书信息
        Book book = bookMapper.selectById(bookItem.getBookId());
        if (book == null) {
            throw new BizException("图书不存在");
        }

        // 计算罚款
        LocalDateTime now = LocalDateTime.now();
        boolean isOverdue = now.isAfter(borrow.getDueDate());
        
        if (isOverdue) {
            long days = ChronoUnit.DAYS.between(borrow.getDueDate(), now);
            borrow.setStatus("overdue");

            // 获取用户借阅规则
            User user = userMapper.selectById(borrow.getUserId());
            if (user == null) {
                throw new BizException("用户不存在");
            }
            
            BorrowRule borrowRule = getBorrowRuleByUserRole(user.getRole());
            if (borrowRule == null) {
                throw new BizException("未找到用户借阅规则");
            }
            
            BigDecimal overdueFee = borrowRule.getOverdueFeePerDay().multiply(BigDecimal.valueOf(days));
            
            // 应用罚款上限（不超过图书价格）
            if (overdueFee.compareTo(book.getPrice()) > 0) {
                overdueFee = book.getPrice();
            }

            // 创建逾期费用记录（未支付）
            FeeRecord feeRecord = new FeeRecord();
            feeRecord.setUserId(borrow.getUserId());
            feeRecord.setRecordId(borrowId);
            feeRecord.setFeeType("overdue_fee");
            feeRecord.setAmount(overdueFee);
            feeRecord.setStatus("unpaid");
            feeRecord.setCreateTime(now);
            feeRecord.setRemark("逾期" + days + "天");
            feeRecordMapper.insert(feeRecord);
        } else {
            borrow.setStatus("returned");
        }

        // 更新借阅记录
        borrow.setReturnDate(now);
        this.updateById(borrow);

        // 更新图书条目状态（只有非逾期状态才更新为在库）
        if (!isOverdue) {
            bookItem.setStatus(BookStatusEnum.IN_STOCK.getCode());
            bookItemMapper.updateById(bookItem);

            // 更新图书可用数量
            book.setAvailableCopies(book.getAvailableCopies() + 1);
            bookMapper.updateById(book);
        }

        // 发送归还通知
        try {
            String content = isOverdue ? 
                "您已归还《" + book.getBookName() + "》，但已逾期，请及时处理相关费用。" :
                "您已成功归还《" + book.getBookName() + "》。";
            Integer notificationId = notificationService.createBorrowNotification(
                borrow.getUserId(),
                borrowId,
                3, // 还书提醒
                "归还成功",
                content
            );
            if (notificationId == null) {
                System.err.println("发送归还通知失败，notificationId为null");
                // 不再显示错误给用户，只记录日志
            }
        } catch (Exception e) {
            // 即使通知发送失败，也不应该影响归还操作本身
            System.err.println("发送归还通知失败: " + e.getMessage());
            e.printStackTrace();
            // 不再显示错误给用户，只记录日志
        }

        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean renewBook(Integer borrowId, Integer days) {
        // 如果days参数为null，设置默认值为15天
        if (days == null) {
            days = 15;
        }
        
        if (days <= 0) {
            throw new BizException("续借天数必须大于0");
        }

        // 检查借阅记录是否存在
        Borrow borrow = this.getById(borrowId);
        if (borrow == null) {
            throw new BizException("借阅记录不存在");
        }

        // 检查借阅状态
        if (!"borrowing".equals(borrow.getStatus())) {
            throw new BizException("当前状态不可续借");
        }

        // 获取用户借阅规则
        User user = userMapper.selectById(borrow.getUserId());
        if (user == null) {
            throw new BizException("用户不存在");
        }
        
        BorrowRule borrowRule = getBorrowRuleByUserRole(user.getRole());
        if (borrowRule == null) {
            throw new BizException("未找到用户借阅规则");
        }
        
        // 检查续借次数限制
        if (borrow.getRenewCount() >= borrowRule.getMaxRenewCount()) {
            throw new BizException("已达到最大续借次数限制：" + borrowRule.getMaxRenewCount() + "次");
        }

        // 检查续借天数限制 - 优先使用系统配置中的续借天数，如果没有则使用借阅规则中的天数
        Integer renewDaysFromConfig = getRenewDaysFromSystemConfig();
        int maxRenewDays = renewDaysFromConfig != null ? renewDaysFromConfig : borrowRule.getRenewDays();
        
        // 确保maxRenewDays大于0，避免出现负数或0的情况
        if (maxRenewDays <= 0) {
            maxRenewDays = 15; // 默认15天
        }
        
        if (days > maxRenewDays) {
            throw new BizException("续借天数不能超过：" + maxRenewDays + "天");
        }

        try {
            // 更新借阅记录
            borrow.setDueDate(borrow.getDueDate().plusDays(days));
            borrow.setRenewCount(borrow.getRenewCount() + 1);
            this.updateById(borrow);
        } catch (Exception e) {
            System.err.println("更新借阅记录失败: " + e.getMessage());
            e.printStackTrace();
            throw new BizException("续借失败：系统异常，请联系管理员");
        }

        // 发送续借通知
        try {
            BookItem bookItem = bookItemMapper.selectById(borrow.getItemId());
            if (bookItem == null) {
                System.err.println("无法找到图书条目，itemId: " + borrow.getItemId());
            } else {
                Book book = bookMapper.selectById(bookItem.getBookId());
                if (book == null) {
                    System.err.println("无法找到图书信息，bookId: " + bookItem.getBookId());
                } else {
                    Integer notificationId = notificationService.createBorrowNotification(
                        borrow.getUserId(),
                        borrowId,
                        2, // 借阅提醒
                        "续借成功",
                        "您已成功续借《" + book.getBookName() + "》，新的归还日期为：" + borrow.getDueDate().toLocalDate()
                    );
                    if (notificationId == null) {
                        System.err.println("发送续借通知失败，notificationId为null");
                    }
                }
            }
        } catch (Exception e) {
            // 即使通知发送失败，也不应该影响续借操作本身
            System.err.println("发送续借通知失败: " + e.getMessage());
            e.printStackTrace();
        }

        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean reportLost(Integer borrowId) {
        // 检查借阅记录是否存在
        Borrow borrow = this.getById(borrowId);
        if (borrow == null) {
            throw new BizException("借阅记录不存在");
        }

        // 检查借阅状态
        if (BorrowStatusEnum.RETURNED.getCode().equals(borrow.getStatus()) || 
            BorrowStatusEnum.LOST.getCode().equals(borrow.getStatus())) {
            throw new BizException("当前状态不可报失");
        }

        // 检查图书条目是否存在
        BookItem bookItem = bookItemMapper.selectById(borrow.getItemId());
        if (bookItem == null) {
            throw new BizException("图书条目不存在");
        }

        // 获取图书信息
        Book book = bookMapper.selectById(bookItem.getBookId());
        if (book == null) {
            throw new BizException("图书不存在");
        }

        // 更新借阅记录
        borrow.setStatus("lost");
        this.updateById(borrow);

        // 创建丢失费用记录（未支付）
        FeeRecord feeRecord = new FeeRecord();
        feeRecord.setUserId(borrow.getUserId());
        feeRecord.setRecordId(borrowId);
        feeRecord.setFeeType("loss_fee");
        feeRecord.setAmount(book.getPrice());
        feeRecord.setStatus("unpaid");
        feeRecord.setCreateTime(LocalDateTime.now());
        feeRecord.setRemark("图书丢失赔偿");
        feeRecordMapper.insert(feeRecord);

        // 更新图书条目状态为异常（丢失的图书标记为异常状态）
        bookItem.setStatus(BookStatusEnum.ABNORMAL.getCode());
        bookItem.setRemark("图书丢失");
        bookItemMapper.updateById(bookItem);

        // 更新图书总数量
        book.setTotalCopies(book.getTotalCopies() - 1);
        bookMapper.updateById(book);

        // 发送丢失通知
        try {
            Integer notificationId = notificationService.createBorrowNotification(
                borrow.getUserId(),
                borrowId,
                5, // 罚款通知
                "图书丢失通知",
                "您借阅的《" + book.getBookName() + "》已被标记为丢失，需支付赔偿金" + book.getPrice() + "元，请及时处理。"
            );
            if (notificationId == null) {
                System.err.println("发送丢失通知失败，notificationId为null");
            }
        } catch (Exception e) {
            // 即使通知发送失败，也不应该影响丢失标记操作本身
            System.err.println("发送丢失通知失败: " + e.getMessage());
            e.printStackTrace();
        }

        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean markOverdue(Integer borrowId) {
        // 检查借阅记录是否存在
        Borrow borrow = this.getById(borrowId);
        if (borrow == null) {
            throw new BizException("借阅记录不存在");
        }

        // 检查借阅状态
        if (!"borrowing".equals(borrow.getStatus())) {
            throw new BizException("只有借阅中的图书可以标记为逾期");
        }

        // 更新借阅记录状态为逾期
        borrow.setStatus("overdue");
        this.updateById(borrow);

        // 计算逾期费用
        LocalDateTime now = LocalDateTime.now();
        long days = ChronoUnit.DAYS.between(borrow.getDueDate(), now);
        if (days <= 0) days = 1; // 至少逾期1天

        // 获取用户借阅规则
        User user = userMapper.selectById(borrow.getUserId());
        if (user == null) {
            throw new BizException("用户不存在");
        }
        
        BorrowRule borrowRule = getBorrowRuleByUserRole(user.getRole());
        if (borrowRule == null) {
            throw new BizException("未找到用户借阅规则");
        }
        
        // 计算罚款金额
        BigDecimal overdueFee = borrowRule.getOverdueFeePerDay().multiply(BigDecimal.valueOf(days));
        
        // 应用罚款上限（不超过图书价格）
        BookItem bookItem = bookItemMapper.selectById(borrow.getItemId());
        Book book = bookMapper.selectById(bookItem.getBookId());
        if (overdueFee.compareTo(book.getPrice()) > 0) {
            overdueFee = book.getPrice();
        }

        // 创建逾期费用记录（未支付）
        FeeRecord feeRecord = new FeeRecord();
        feeRecord.setUserId(borrow.getUserId());
        feeRecord.setRecordId(borrowId);
        feeRecord.setFeeType("overdue_fee");
        feeRecord.setAmount(overdueFee);
        feeRecord.setStatus("unpaid");
        feeRecord.setCreateTime(now);
        feeRecord.setRemark("逾期" + days + "天");
        feeRecordMapper.insert(feeRecord);

        // 发送逾期通知
        try {
            Integer notificationId = notificationService.createBorrowNotification(
                borrow.getUserId(),
                borrowId,
                4, // 逾期提醒
                "图书逾期通知",
                "您借阅的《" + book.getBookName() + "》已逾期" + days + "天，需支付逾期费用" + overdueFee + "元，请及时处理。"
            );
            if (notificationId == null) {
                System.err.println("发送逾期通知失败，notificationId为null");
            }
        } catch (Exception e) {
            // 即使通知发送失败，也不应该影响逾期标记操作本身
            System.err.println("发送逾期通知失败: " + e.getMessage());
            e.printStackTrace();
            // 不再显示错误给用户，只记录日志
        }

        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean payFine(Integer borrowId) {
        // 逻辑迁移到 fee_record：将该借阅的未支付费用置为已支付
        LambdaQueryWrapper<FeeRecord> qw = new LambdaQueryWrapper<>();
        qw.eq(FeeRecord::getRecordId, borrowId)
          .eq(FeeRecord::getStatus, "unpaid");
        List<FeeRecord> records = feeRecordMapper.selectList(qw);
        if (records == null || records.isEmpty()) {
            throw new BizException("没有需要支付的费用");
        }
        LocalDateTime now = LocalDateTime.now();
        for (FeeRecord fr : records) {
            fr.setStatus("paid");
            fr.setPayTime(now);
            feeRecordMapper.updateById(fr);
        }

        // 如果是丢失的图书，支付完成后更新借阅状态为已归还
        Borrow borrow = this.getById(borrowId);
        if (borrow != null && "lost".equals(borrow.getStatus())) {
            borrow.setStatus("returned"); // 使用数据库允许的枚举值
            borrow.setReturnDate(now);
            this.updateById(borrow);
            
            // 更新图书条目状态为在库
            BookItem bookItem = bookItemMapper.selectById(borrow.getItemId());
            if (bookItem != null) {
                bookItem.setStatus(BookStatusEnum.IN_STOCK.getCode());
                bookItemMapper.updateById(bookItem);
            }
        }

        // 发送支付成功通知
        try {
            // 获取图书信息
            BookItem bookItem = bookItemMapper.selectById(borrow.getItemId());
            if (bookItem != null) {
                Book book = bookMapper.selectById(bookItem.getBookId());
                if (book != null) {
                    Integer notificationId = notificationService.createBorrowNotification(
                        borrow.getUserId(),
                        borrowId,
                        5, // 罚款通知
                        "费用支付成功",
                        "您已成功支付《" + book.getBookName() + "》的相关费用。"
                    );
                    if (notificationId == null) {
                        System.err.println("发送支付成功通知失败，notificationId为null");
                        // 不再显示错误给用户，只记录日志
                    }
                }
            }
        } catch (Exception e) {
            // 即使通知发送失败，也不应该影响支付操作本身
            System.err.println("发送支付成功通知失败: " + e.getMessage());
            e.printStackTrace();
            // 不再显示错误给用户，只记录日志
        }

        return true;
    }

    @Override
    public Double getFineAmount(Integer borrowId) {
        // 查询未支付的费用记录
        LambdaQueryWrapper<FeeRecord> qw = new LambdaQueryWrapper<>();
        qw.eq(FeeRecord::getRecordId, borrowId)
          .eq(FeeRecord::getStatus, "unpaid");
        List<FeeRecord> records = feeRecordMapper.selectList(qw);
        
        if (records == null || records.isEmpty()) {
            return 0.0;
        }
        
        // 计算总费用
        BigDecimal totalAmount = BigDecimal.ZERO;
        for (FeeRecord fr : records) {
            totalAmount = totalAmount.add(fr.getAmount());
        }
        
        return totalAmount.doubleValue();
    }

    @Override
    public BorrowVO getBorrowById(Integer borrowId) {
        // 查询借阅记录
        Borrow borrow = this.getById(borrowId);
        if (borrow == null) {
            throw new BizException("借阅记录不存在");
        }

        // 转换为VO
        return convertToVO(borrow);
    }

    @Override
    public IPage<BorrowVO> pageBorrows(Integer page, Integer size, Integer userId, String status, String keyword) {
        try {
            // 构建查询条件
            LambdaQueryWrapper<Borrow> queryWrapper = new LambdaQueryWrapper<>();
            if (userId != null) {
                queryWrapper.eq(Borrow::getUserId, userId);
            }
            if (StringUtils.isNotBlank(status)) {
                String statusStr = null;
                switch (status) {
                    case "borrowing":
                    case "1": statusStr = "borrowing"; break;
                    case "returned":
                    case "2": statusStr = "returned"; break;
                    case "overdue":
                    case "3": statusStr = "overdue"; break;
                    case "lost":
                    case "4": statusStr = "lost"; break;
                    default: statusStr = null;
                }
                if (statusStr != null) {
                    queryWrapper.eq(Borrow::getStatus, statusStr);
                }
            }

            // 分页查询
            Page<Borrow> borrowPage = new Page<>(page, size);
            Page<Borrow> resultPage = this.page(borrowPage, queryWrapper);

            // 转换为VO
            List<BorrowVO> borrowVOList = resultPage.getRecords().stream()
                    .map(this::convertToVO)
                    .filter(vo -> vo != null) // 过滤掉null值
                    .collect(Collectors.toList());

            // 如果有关键字，进行过滤
            if (StringUtils.isNotBlank(keyword)) {
                borrowVOList = borrowVOList.stream()
                        .filter(vo -> (vo.getBookName() != null && vo.getBookName().contains(keyword)) ||
                                (vo.getIsbn() != null && vo.getIsbn().contains(keyword)) ||
                                (vo.getUsername() != null && vo.getUsername().contains(keyword)) ||
                                (vo.getRealName() != null && vo.getRealName().contains(keyword)))
                        .collect(Collectors.toList());
            }

            // 构建返回结果
            Page<BorrowVO> voPage = new Page<>(resultPage.getCurrent(), resultPage.getSize(), resultPage.getTotal());
            voPage.setRecords(borrowVOList);

            return voPage;
        } catch (Exception e) {
            System.err.println("分页查询借阅记录时出现异常: " + e.getMessage());
            e.printStackTrace();
            // 返回空的分页结果
            Page<BorrowVO> emptyPage = new Page<>(page, size, 0);
            emptyPage.setRecords(new ArrayList<>());
            return emptyPage;
        }
    }

    @Override
    public IPage<BorrowVO> getCurrentBorrows(Integer userId, Integer page, Integer size) {
        try {
            // 构建查询条件
            LambdaQueryWrapper<Borrow> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Borrow::getUserId, userId)
                    .eq(Borrow::getStatus, "borrowing");

            // 分页查询
            Page<Borrow> borrowPage = new Page<>(page, size);
            Page<Borrow> resultPage = this.page(borrowPage, queryWrapper);

            // 转换为VO
            List<BorrowVO> borrowVOList = resultPage.getRecords().stream()
                    .map(this::convertToVO)
                    .filter(vo -> vo != null)
                    .collect(Collectors.toList());

            // 构建返回结果
            Page<BorrowVO> voPage = new Page<>(resultPage.getCurrent(), resultPage.getSize(), resultPage.getTotal());
            voPage.setRecords(borrowVOList);

            return voPage;
        } catch (Exception e) {
            System.err.println("获取用户当前借阅记录时出现异常: " + e.getMessage());
            e.printStackTrace();
            Page<BorrowVO> emptyPage = new Page<>(page, size, 0);
            emptyPage.setRecords(new ArrayList<>());
            return emptyPage;
        }
    }

    @Override
    public IPage<BorrowVO> getOverdueBorrows(Integer page, Integer size) {
        try {
            // 构建查询条件：状态为 overdue
            LambdaQueryWrapper<Borrow> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Borrow::getStatus, "overdue");

            // 分页查询
            Page<Borrow> borrowPage = new Page<>(page, size);
            Page<Borrow> resultPage = this.page(borrowPage, queryWrapper);

            // 转换为VO
            List<BorrowVO> borrowVOList = resultPage.getRecords().stream()
                    .map(this::convertToVO)
                    .filter(vo -> vo != null)
                    .collect(Collectors.toList());

            // 构建返回结果
            Page<BorrowVO> voPage = new Page<>(resultPage.getCurrent(), resultPage.getSize(), resultPage.getTotal());
            voPage.setRecords(borrowVOList);

            return voPage;
        } catch (Exception e) {
            System.err.println("获取逾期借阅记录时出现异常: " + e.getMessage());
            e.printStackTrace();
            Page<BorrowVO> emptyPage = new Page<>(page, size, 0);
            emptyPage.setRecords(new ArrayList<>());
            return emptyPage;
        }
    }

    /**
     * 根据用户角色获取借阅规则
     */
    private BorrowRule getBorrowRuleByUserRole(String userRole) {
        if (StringUtils.isBlank(userRole)) {
            userRole = "normal_user"; // 默认角色
        }
        
        LambdaQueryWrapper<BorrowRule> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BorrowRule::getRole, userRole);
        return borrowRuleMapper.selectOne(queryWrapper);
    }

    /**
     * 将Borrow实体转换为BorrowVO
     * @param borrow 借阅实体
     * @return 借阅VO
     */
    private BorrowVO convertToVO(Borrow borrow) {
        if (borrow == null) {
            return null;
        }
        BorrowVO borrowVO = new BorrowVO();
        
        // 手动设置所有字段，避免BeanUtil.copyProperties的问题
        borrowVO.setBorrowId(borrow.getBorrowId());
        borrowVO.setUserId(borrow.getUserId());
        borrowVO.setItemId(borrow.getItemId());
        borrowVO.setRenewCount(borrow.getRenewCount());
        
        // 时间字段映射
        borrowVO.setBorrowTime(borrow.getBorrowDate());
        borrowVO.setDueTime(borrow.getDueDate());
        borrowVO.setReturnTime(borrow.getReturnDate());

        // 查询用户信息
        User user = userMapper.selectById(borrow.getUserId());
        if (user != null) {
            borrowVO.setUsername(user.getUsername());
            borrowVO.setRealName(user.getRealName());
        }

        // 查询图书信息（通过 Item 反查 Book）
        BookItem item = bookItemMapper.selectById(borrow.getItemId());
        Book book = (item != null) ? bookMapper.selectById(item.getBookId()) : null;
        if (book != null) {
            borrowVO.setBookId(book.getBookId());
            borrowVO.setBookName(book.getBookName());
            borrowVO.setIsbn(book.getIsbn());
            borrowVO.setAuthor(book.getAuthor());
        }

        // 设置状态与描述
        String status = borrow.getStatus();
        borrowVO.setStatus(status);
        if ("borrowing".equals(status)) { 
            borrowVO.setStatusDesc("借阅中"); 
        } else if ("returned".equals(status)) { 
            // 检查是否是丢失后赔付完成的记录
            LambdaQueryWrapper<FeeRecord> feeQueryWrapper = new LambdaQueryWrapper<>();
            feeQueryWrapper.eq(FeeRecord::getRecordId, borrow.getBorrowId());
            feeQueryWrapper.eq(FeeRecord::getFeeType, "loss_fee");
            feeQueryWrapper.eq(FeeRecord::getStatus, "paid");
            FeeRecord paidLossFee = feeRecordMapper.selectOne(feeQueryWrapper);
            
            if (paidLossFee != null) {
                borrowVO.setStatusDesc("已赔付");
            } else {
                borrowVO.setStatusDesc("已归还"); 
            }
        } else if ("overdue".equals(status)) { 
            borrowVO.setStatusDesc("逾期"); 
        } else if ("lost".equals(status)) { 
            borrowVO.setStatusDesc("丢失");
        } else {
            borrowVO.setStatusDesc(status);
        }

        return borrowVO;
    }

    /**
     * 从系统配置中获取续借天数
     * @return 续借天数，如果未配置则返回null
     */
    private Integer getRenewDaysFromSystemConfig() {
        try {
            // 从系统配置中获取续借天数配置
            String renewDaysStr = systemConfigService.getConfigValue("renew_days");
            if (renewDaysStr != null && !renewDaysStr.isEmpty()) {
                return Integer.valueOf(renewDaysStr);
            }
            return null;
        } catch (Exception e) {
            System.err.println("获取系统配置续借天数失败: " + e.getMessage());
            return null;
        }
    }
}